package com.ltxtiyu.video.tool;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {

    public static final String chineseChar = "\\u3400-\\u4DB5\\u4E00-\\u9FA5\\u9FA6-\\u9FBB\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFF00-\\uFFEF\\u2E80-\\u2EFF\\u3000-\\u303F\\u31C0-\\u31EF\\u2F00-\\u2FDF\\u2FF0-\\u2FFF\\u3100-\\u312F\\u31A0-\\u31BF\\u3040-\\u309F\\u30A0-\\u30FF\\u31F0-\\u31FF\\uAC00-\\uD7AF\\u1100-\\u11FF\\u3130-\\u318F\\u4DC0-\\u4DFF\\uA000-\\uA48F\\uA490-\\uA4CF\\u2800-\\u28FF\\u3200-\\u32FF\\u3300-\\u33FF\\u2700-\\u27BF\\u2600-\\u26FF\\uFE10-\\uFE1F\\uFE30-\\uFE4F";
    public static final String num09 = "\\u0030-\\u0039";
    public static final String caz = "\\u0061-\\u007a";
    public static final String cAZ = "\\u0041-\\u005a";
    public static final String ascii = "\\u000a\\u0020-\\u007e";

    public static final String reg = "[^" + chineseChar + ascii + "]";
    
    // 正则表达式规则
    public static final String regEx="^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(.*)$";
    
    public static final String DATE_LENGTH = "yyyy-MM-dd HH:mm:ss";
    
    public static boolean isCheckDateString( String str){
	    
	    // 编译正则表达式
	    Pattern pattern = Pattern.compile(regEx);
	    // 忽略大小写的写法
	    // Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
	    Matcher matcher = pattern.matcher(str);
	    // 查找字符串中是否有匹配正则表达式的字符/字符串
	    boolean rs = matcher.find();
	    return rs;
    }

    public static String filterEmoji(String str) {
        if (StringUtils.isNotBlank(str)) {
            return str.replaceAll(reg, " ");
        } else {
            return str;
        }
    }
    
    public static boolean isBlank(CharSequence cs){
    	int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }
    public static boolean isNotBlank(CharSequence cs){
        return isBlank(cs)?false:true;
    }
    
    /**
     * 截取字符串
     * @return
     */
    public static String subString(String str, int beginIndex, int endIndex){
    	String result = "";
    	if(!StringUtils.isBlank(str)){
    		result = str.substring(beginIndex, endIndex);
    	}
    	return result;
    }
    
    /**
     * 截掉最后一位
     * @param str
     * @param sub
     * @return
     */
    public static String subLastOne(String str, String sub){
    	if(isNotBlank(str)){
    		String lastOneStr = str.substring(str.length()-1,str.length());
    		if(lastOneStr.equals(sub)){
    			return str.substring(0, str.length()-1);
    		}
    	}
    	return str;
    } 
    
	/**
	 * 根据字符串获得属性值
	 * @param fieldName
	 * @param o
	 * @return
	 */
	public static Object getFieldValueByName(String fieldName, Object o) {
		try {
			String firstLetter = fieldName.substring(0, 1).toUpperCase();
			String getter = "get" + firstLetter + fieldName.substring(1);
			Method method = o.getClass().getMethod(getter, new Class[] {});
			Object value = method.invoke(o, new Object[] {});
			return value;
		} catch (Exception e) {
			//System.out.println("属性不存在");
			return null;
		}
	}
	public static Integer numberNullConvert(String o, Integer b){
		Integer result = 0;
		try {
			result = Integer.valueOf(o);
		} catch (Exception e) {
			return b;
		}
		return result;
	}
	public static Integer numberNullConvert(String o){
		Integer result = 0;
		try {
			result = Integer.valueOf(o);
		} catch (Exception e) {
			return null;
		}
		return result;
	}
	public static BigDecimal numberNullConvert(String o, BigDecimal b){
		BigDecimal result = BigDecimal.ZERO;
		try {
			result = new BigDecimal(o);
		} catch (Exception e) {
			return b;
		}
		return result;
	}
	

	/**判断
	 * object对象是否为null
	 * @param obj
	 * @return
	 */
	public static boolean isNullOrEmpty(Object obj){
        if (obj == null)  
            return true;  
  
        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;
  
        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();
  
        if (obj instanceof Map)
            return ((Map) obj).isEmpty();
  
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {  
                return true;  
            }  
            boolean empty = true;  
            for (int i = 0; i < object.length; i++) {  
                if (!isNullOrEmpty(object[i])) {  
                    empty = false;  
                    break;  
                }  
            }  
            return empty;  
        }  
        return false;  
    }
	
	public static boolean isNotObjectDefault(Object obj, String pType){
		boolean flag = true;
		if("isTrue".equals(pType)){
			if(obj.getClass().getName().equals(Integer.class.getName())){
				if(new Integer(obj.toString())>0){
					flag = false;
				}
			}
		}
		 if (obj == null)  
	            return true;  
        if (obj instanceof CharSequence)
            return ((CharSequence) obj).length() == 0;
  
        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();
  
        if (obj instanceof Map)
            return ((Map) obj).isEmpty();
  
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {  
                return true;  
            }  
            boolean empty = true;  
            for (int i = 0; i < object.length; i++) {  
                if (!isNullOrEmpty(object[i])) {  
                    empty = false;  
                    break;  
                }  
            }  
            return empty;  
        }
		
		if(obj.getClass().getName().equals(BigDecimal.class.getName())){
			if(new BigDecimal(obj.toString()).compareTo(BigDecimal.ZERO)>=0){
				flag = false;
			}
		}
		if(obj.getClass().getName().equals(Double.class.getName())){
			if(new Double(obj.toString())>=0.0){
				flag = false;
			}
		}
		if(obj.getClass().getName().equals(Integer.class.getName())){
			if(new Integer(obj.toString())>=0){
				flag = false;
			}
		}
		return flag;
	}
	/**
	 * 格式化数字
	 * @param mat
	 * @param number
	 * @return
	 */
	public static String numberFormat(String mat, BigDecimal number){
	    	DecimalFormat df = new DecimalFormat(mat);
	    	return df.format(number);
	}
	/**
	 * 格式化日期
	 * @param format
	 * @return
	 */
	public static String dateFormat(String format){
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.format(new Date());
	}
	
	/**
	 * 格式化时间
	 * 作者：bsun
	 * 2016年11月7日 下午5:00:37
	 * @param date
	 * @param format
	 * @return
	 */
	public static String dateFormatInfo(Date date, String format){
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}
	
	/**
	 * 产生随机数
	 * @param n
	 * @return
	 */
	public static int rand(int n) {
		int ans = 0;
		while (Math.log10(ans) + 1 < n)
			ans = (int) (Math.random() * Math.pow(10, n));
		return ans;
	}
	/**
	 * 比较日期间隔
	 * @param smdate
	 * @param bdate
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static int daysBetween(Date smdate, Date bdate, String format) throws ParseException
    {    
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        smdate=sdf.parse(sdf.format(smdate));  
        bdate=sdf.parse(sdf.format(bdate));  
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);    
        long time1 = cal.getTimeInMillis();                 
        cal.setTime(bdate);    
        long time2 = cal.getTimeInMillis();         
        long between_days=(time2-time1)/(1000*3600*24);  
       return Integer.parseInt(String.valueOf(between_days));
    }
	
	/**
	 * 根据性别转换称呼,true先生false女士
	 * @param name
	 * @param gender
	 * @return
	 */
	public static String chineseNameByGender(String name, boolean gender){
		String result = "";
		if(!StringUtil.isBlank(name)){
			result = name.substring(0,1);
		}
		if(gender){
			result = result+"先生";
		}else{
			result = result+"女士";
		}
		return result;
	}
	
	/**
	 * 没有性别
	 * @param name
	 * @return
	 */
	public static String chineseNameByNotGender(String name){
		String result = "";
		if(!StringUtil.isBlank(name)){
			result = name.substring(0,1);
		}
		result = result+"先生/女士";
		return result;
	}
	
	/** 
     * [中文姓名] 只显示第一个汉字，其他隐藏为2个星号<例子：李**> 
     *  
     * @return
     */  
    public static String chineseName(String fullName) {
        if (StringUtils.isBlank(fullName)) {  
            return "";  
        }  
        String name = StringUtils.left(fullName, 1);
        return StringUtils.rightPad(name, StringUtils.length(fullName), "*");  
    }
    /** 
     * [中文姓名] 姓氏换*<例子：*菲菲> 
     *  
     * @return
     */  
    public static String chineseNameSur(String fullName) {
        if (StringUtils.isBlank(fullName)) {  
            return "";  
        }  
        String name = StringUtils.right(fullName, fullName.length()-1);
        return StringUtils.leftPad(name, StringUtils.length(fullName), "*");  
    }
    /** 
     * [身份证号] 显示最后四位，其他隐藏。共计18位或者15位。<例子：*************5762> 
     *  
     * @param id 
     * @return 
     */  
    public static String idCardNum(String id) {
        if (StringUtils.isBlank(id)) {  
            return "";  
        }  
        String num = StringUtils.right(id, 4);
        return StringUtils.leftPad(num, StringUtils.length(id), "*");  
    }
    
    /** 
     * [身份证号] 显示前八位最后四位，其他隐藏。共计18位或者15位。<例子：31108119***********5762> 
     *  
     * @param id 
     * @return 
     */  
    public static String idCardNum8_4(String id) {
        if (StringUtils.isBlank(id)) {  
            return "";  
        }  
        return StringUtils.left(id, 8).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(id, 4), StringUtils.length(id), "*"), "***"));
    }
    
    /**
     * 校验身份证号
     * @param idcard
     * @return
     */
    public static boolean idCardCheck(String idcard){
    	 boolean result = false;
         if (idcard.length() == 18) {
             result = Pattern.matches("^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X|x)$",idcard);
         } else if (idcard.length() == 15) {
             result = Pattern.matches( "^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$",idcard);
         }
         return result;
    }
    
    /** 
     * [固定电话] 后四位，其他隐藏<例子：****1234> 
     *  
     * @param num 
     * @return 
     */  
    public static String fixedPhone(String num) {
        if (StringUtils.isBlank(num)) {  
            return "";  
        }  
        return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");  
    }  
  
    /** 
     * [手机号码] 前三位，后四位，其他隐藏<例子:138******1234> 
     *  
     * @param num 
     * @return 
     */  
    public static String mobilePhone(String num) {
        if (StringUtils.isBlank(num)) {  
            return "";  
        }  
        return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"), "***"));  
    }  
  
    /** 
     * [地址] 只显示到地区，不显示详细地址；我们要对个人信息增强保护<例子：北京市海淀区****> 
     *  
     * @param address 
     * @param sensitiveSize 
     *            敏感信息长度 
     * @return 
     */  
    public static String address(String address, int sensitiveSize) {
        if (StringUtils.isBlank(address)) {  
            return "";  
        }  
        int length = StringUtils.length(address);  
        return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");  
    }  
  
    /** 
     * [电子邮箱] 邮箱前缀仅显示第一个字母，前缀其他隐藏，用星号代替，@及后面的地址显示<例子:g**@163.com> 
     *  
     * @param email 
     * @return 
     */  
    public static String email(String email) {
        if (StringUtils.isBlank(email)) {  
            return "";  
        }  
        int index = StringUtils.indexOf(email, "@");  
        if (index <= 1)  
            return email;  
        else  
            return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));  
    }  
  
    /** 
     * [银行卡号] 前六位，后四位，其他用星号隐藏每位1个星号<例子:6222600**********1234> 
     *  
     * @param cardNum 
     * @return 
     */  
    public static String bankCard(String cardNum) {
        if (StringUtils.isBlank(cardNum)) {  
            return "";  
        }  
        return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));  
    }  
  
    /** 
     * [公司开户银行联号] 公司开户银行联行号,显示前两位，其他用星号隐藏，每位1个星号<例子:12********> 
     *  
     * @param code 
     * @return 
     */  
    public static String cnapsCode(String code) {
        if (StringUtils.isBlank(code)) {  
            return "";  
        }  
        return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");  
    }
    
    /**
     * 生成流水号
     * @param type 类型
     * @return
     */
    public static String getSerialNumber(String type){
    	StringBuffer result = new StringBuffer();
    	result.append(type+dateFormat("yyyyMMddhhmmss")+rand(4));
    	return result.toString();
    }
  
    public static String nameNullConvert(String name, String mobile) {
        return StringUtils.isBlank(name) ? (StringUtils.isBlank(mobile) ? "" : mobile.substring(0, 1)+"***"+mobile.substring(mobile.length()-1)) : name;
    }
    public static boolean chineseNameCheck(String name) {
        if (!name.matches("[\u4e00-\u9fa5]{2,6}")) {
            return false;
        }else 
        	return true;
    }
    /**
     * 将字符串转为 UTF-8
     * 作者：bsun
     * 2016年11月9日 下午5:42:20
     * @param orgStr
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String ToUTF8String(String orgStr) throws UnsupportedEncodingException {
		return new String(orgStr.getBytes("ISO8859-1"), "UTF-8");
	}
    
    /**
     * 十六进制转换十进制
     * @param len
     * @return
     */
    public static Long parseLong10(String len){
    	return Long.parseLong(len, 16);
    }
    
    /**
     * 判断字符串不为空
     * 作者：bsun
     * 2016年12月30日 下午1:48:36
     * @param inputStr
     * @return boolean
     */
	public static  boolean isNotBlank(String inputStr){
		return isBlank(inputStr)?false:true;
	}
	
	/**
	 * 将逗号分隔的字符串转换为Integer数组
	 * @param str
	 * @return
	 */
	public static List<Integer> stringToIntegers(String str){
		List<Integer> list = new ArrayList<Integer>();
		try {
			if(!isBlank(str)){
				String[] strLen = str.split(",");
				if(strLen.length>0){
					for (int i = 0; i < strLen.length; i++) {
						try {
							list.add(Integer.valueOf(strLen[i]));
						} catch (Exception e) {
							continue;
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
    
	/**
	 * 生成流水号
	 * @return
	 */
	public static String getSerialNumber(){
		String result = rand(4)+dateFormatInfo(new Date(), "yyyyMMddHHmm");
		return result;
	}
	
	/**
	 * 生成支付订单号
	 * @return
	 */
	public static String outTradeNo(Integer payType){
		String result = payType+dateFormatInfo(new Date(), "yyyyMMddHHmmss")+rand(6);
		return result;
	}

	/**
	 * 修改广告位url的channel值
	 * @param url
	 * @param channel
	 * @return
	 */
	public static String appPicUrlIsCheckChannel(String url, String channel){
		if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(channel)) {  
            url = url.replaceAll("(channel=[^&]*)", "channel=" + channel);  
        }  
		return url;
	}

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }
}
